package com.zhentao.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhentao.common.Result;
import com.zhentao.pojo.Countries;
import com.zhentao.pojo.Ports;
import com.zhentao.pojo.UserPortFavorites;
import com.zhentao.service.CountriesService;
import com.zhentao.service.PortsService;
import com.zhentao.service.UserPortFavoritesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

@RestController
@RequestMapping("/map")
//@CrossOrigin(origins = {"http://localhost:5173","http://127.0.0.1:5173"}, allowCredentials = "true")
public class MapController {

    private static final Logger logger = LoggerFactory.getLogger(MapController.class);

    @Autowired
    private PortsService portsService;
    
    @Autowired
    private UserPortFavoritesService userPortFavoritesService;
    
    @Autowired
    private CountriesService countriesService;

    /**
     * 添加/取消港口收藏
     * @param userId 用户ID
     * @param portId 港口ID
     * @return 操作结果
     */
    @PostMapping("/favorite")
    public Result<Map<String, Object>> togglePortFavorite(@RequestParam Long userId, @RequestParam Long portId) {
        try {
            logger.info("用户{}操作港口{}收藏状态", userId, portId);
            
            // 检查是否已收藏
            LambdaQueryWrapper<UserPortFavorites> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserPortFavorites::getUserId, userId)
                       .eq(UserPortFavorites::getPortId, portId);
            
            UserPortFavorites existing = userPortFavoritesService.getOne(queryWrapper);
            
            Map<String, Object> response = new HashMap<>();
            
            if (existing != null) {
                // 已收藏，执行取消收藏
                userPortFavoritesService.removeById(existing.getId());
                response.put("isFavorited", false);
                response.put("message", "取消收藏成功");
                logger.info("用户{}取消收藏港口{}", userId, portId);
            } else {
                // 未收藏，执行收藏
                UserPortFavorites favorite = new UserPortFavorites();
                favorite.setUserId(userId);
                favorite.setPortId(portId);
                favorite.setCreatedAt(new Date());
                favorite.setUpdatedAt(new Date());
                
                userPortFavoritesService.save(favorite);
                response.put("isFavorited", true);
                response.put("message", "收藏成功");
                logger.info("用户{}收藏港口{}", userId, portId);
            }
            
            return Result.success(response);
            
        } catch (Exception e) {
            logger.error("操作港口收藏失败: ", e);
            return Result.error("操作失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户收藏的港口列表（支持分页）
     * @param userId 用户ID
     * @param page 页码
     * @param size 每页大小
     * @param userLat 用户当前纬度（可选，用于距离计算）
     * @param userLng 用户当前经度（可选，用于距离计算）
     * @return 收藏港口列表
     */
    @GetMapping("/favorites")
    public Result<Map<String, Object>> getUserFavoritePorts(
            @RequestParam Long userId,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) Double userLat,
            @RequestParam(required = false) Double userLng) {
        
        try {
            logger.info("获取用户{}收藏港口列表，页码: {}, 每页大小: {}", userId, page, size);
            
            // 创建分页对象
            Page<UserPortFavorites> pageInfo = new Page<>(page, size);
            
            // 查询用户收藏记录
            LambdaQueryWrapper<UserPortFavorites> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserPortFavorites::getUserId, userId)
                       .orderByDesc(UserPortFavorites::getCreatedAt);
            
            Page<UserPortFavorites> favoritesResult = userPortFavoritesService.page(pageInfo, queryWrapper);
            
            // 获取港口详情
            List<Map<String, Object>> favoritePortsWithDetails = new ArrayList<>();
            
            for (UserPortFavorites favorite : favoritesResult.getRecords()) {
                Ports port = portsService.getById(favorite.getPortId());
                if (port != null) {
                    Map<String, Object> portInfo = new HashMap<>();
                    portInfo.put("favoriteId", favorite.getId());
                    portInfo.put("favoriteTime", favorite.getCreatedAt());
                    
                    // 港口基本信息
                    portInfo.put("id", port.getId());
                    portInfo.put("name", port.getName());
                    portInfo.put("portCode", port.getPortCode());
                    portInfo.put("description", port.getDescription());
                    portInfo.put("region", port.getRegion());
                    portInfo.put("timezone", port.getTimezone());
                    portInfo.put("latitude", port.getLatitude());
                    portInfo.put("longitude", port.getLongitude());
                    portInfo.put("isPopular", port.getIsPopular());
                    portInfo.put("isFavorited", true);
                    
                    // 获取国家信息
                    if (port.getCountryId() != null) {
                        Countries country = countriesService.getById(port.getCountryId());
                        if (country != null) {
                            portInfo.put("countryId", country.getId());
                            portInfo.put("countryName", country.getName());
                            portInfo.put("countryNameEn", country.getNameEn());
                            portInfo.put("flag", country.getFlag());
                        }
                    }
                    
                    // 计算距离（如果提供了用户坐标）
                    if (userLat != null && userLng != null && 
                        port.getLatitude() != null && port.getLongitude() != null) {
                        double distance = calculateDistance(userLat, userLng, 
                                                          port.getLatitude().doubleValue(), 
                                                          port.getLongitude().doubleValue());
                        portInfo.put("distance", Math.round(distance * 100.0) / 100.0); // 保留2位小数
                    }
                    
                    favoritePortsWithDetails.add(portInfo);
                }
            }
            
            // 构建返回结果
            Map<String, Object> response = new HashMap<>();
            response.put("list", favoritePortsWithDetails);
            response.put("total", favoritesResult.getTotal());
            response.put("pages", favoritesResult.getPages());
            response.put("current", favoritesResult.getCurrent());
            response.put("size", favoritesResult.getSize());
            
            return Result.success(response);
            
        } catch (Exception e) {
            logger.error("获取用户收藏港口列表失败: ", e);
            return Result.error("获取收藏列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取附近港口列表（按距离排序）
     * @param userLat 用户纬度
     * @param userLng 用户经度
     * @param radius 搜索半径（公里，默认100公里）
     * @param userId 用户ID（可选，用于标识收藏状态）
     * @param page 页码
     * @param size 每页大小
     * @return 附近港口列表
     */
    @GetMapping("/nearby")
    public Result<Map<String, Object>> getNearbyPorts(
            @RequestParam Double userLat,
            @RequestParam Double userLng,
            @RequestParam(defaultValue = "100") Double radius,
            @RequestParam(required = false) Long userId,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        
        try {
            logger.info("获取用户坐标({}, {})附近{}公里内的港口", userLat, userLng, radius);
            
            // 获取所有启用的港口
            QueryWrapper<Ports> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1)
                       .isNotNull("latitude")
                       .isNotNull("longitude");
            
            List<Ports> allPorts = portsService.list(queryWrapper);
            
            // 计算距离并过滤
            List<Map<String, Object>> nearbyPorts = new ArrayList<>();
            Set<Long> userFavoritePortIds = new HashSet<>();
            
            // 如果提供了用户ID，获取用户收藏的港口ID列表
            if (userId != null) {
                LambdaQueryWrapper<UserPortFavorites> favoriteQuery = new LambdaQueryWrapper<>();
                favoriteQuery.eq(UserPortFavorites::getUserId, userId);
                List<UserPortFavorites> favorites = userPortFavoritesService.list(favoriteQuery);
                userFavoritePortIds = new HashSet<>();
                for (UserPortFavorites favorite : favorites) {
                    userFavoritePortIds.add(favorite.getPortId());
                }
            }
            
            for (Ports port : allPorts) {
                if (port.getLatitude() != null && port.getLongitude() != null) {
                    double distance = calculateDistance(userLat, userLng,
                                                      port.getLatitude().doubleValue(),
                                                      port.getLongitude().doubleValue());
                    
                    if (distance <= radius) {
                        Map<String, Object> portInfo = new HashMap<>();
                        portInfo.put("id", port.getId());
                        portInfo.put("name", port.getName());
                        portInfo.put("portCode", port.getPortCode());
                        portInfo.put("description", port.getDescription());
                        portInfo.put("region", port.getRegion());
                        portInfo.put("timezone", port.getTimezone());
                        portInfo.put("latitude", port.getLatitude());
                        portInfo.put("longitude", port.getLongitude());
                        portInfo.put("isPopular", port.getIsPopular());
                        portInfo.put("distance", Math.round(distance * 100.0) / 100.0);
                        portInfo.put("isFavorited", userFavoritePortIds.contains(port.getId()));
                        
                        // 获取国家信息
                        if (port.getCountryId() != null) {
                            Countries country = countriesService.getById(port.getCountryId());
                            if (country != null) {
                                portInfo.put("countryId", country.getId());
                                portInfo.put("countryName", country.getName());
                                portInfo.put("countryNameEn", country.getNameEn());
                                portInfo.put("flag", country.getFlag());
                            }
                        }
                        
                        nearbyPorts.add(portInfo);
                    }
                }
            }
            
            // 按距离排序
            nearbyPorts.sort((a, b) -> {
                Double distanceA = (Double) a.get("distance");
                Double distanceB = (Double) b.get("distance");
                return Double.compare(distanceA, distanceB);
            });
            
            // 手动分页
            int total = nearbyPorts.size();
            int startIndex = (page - 1) * size;
            int endIndex = Math.min(startIndex + size, total);
            
            List<Map<String, Object>> pagedPorts = nearbyPorts.subList(startIndex, endIndex);
            
            Map<String, Object> response = new HashMap<>();
            response.put("list", pagedPorts);
            response.put("total", total);
            response.put("pages", (int) Math.ceil((double) total / size));
            response.put("current", page);
            response.put("size", size);
            response.put("radius", radius);
            
            return Result.success(response);
            
        } catch (Exception e) {
            logger.error("获取附近港口失败: ", e);
            return Result.error("获取附近港口失败: " + e.getMessage());
        }
    }

    /**
     * 检查港口收藏状态
     * @param userId 用户ID
     * @param portId 港口ID
     * @return 收藏状态
     */
    @GetMapping("/favorite/status")
    public Result<Map<String, Object>> checkFavoriteStatus(@RequestParam Long userId, @RequestParam Long portId) {
        try {
            LambdaQueryWrapper<UserPortFavorites> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserPortFavorites::getUserId, userId)
                       .eq(UserPortFavorites::getPortId, portId);
            
            UserPortFavorites favorite = userPortFavoritesService.getOne(queryWrapper);
            
            Map<String, Object> response = new HashMap<>();
            response.put("isFavorited", favorite != null);
            if (favorite != null) {
                response.put("favoriteTime", favorite.getCreatedAt());
            }
            
            return Result.success(response);
            
        } catch (Exception e) {
            logger.error("检查收藏状态失败: ", e);
            return Result.error("检查收藏状态失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户收藏港口统计信息
     * @param userId 用户ID
     * @return 统计信息
     */
    @GetMapping("/favorites/stats")
    public Result<Map<String, Object>> getFavoriteStats(@RequestParam Long userId) {
        try {
            LambdaQueryWrapper<UserPortFavorites> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserPortFavorites::getUserId, userId);
            
            long totalFavorites = userPortFavoritesService.count(queryWrapper);
            
            // 按国家统计收藏港口数量
            List<UserPortFavorites> favorites = userPortFavoritesService.list(queryWrapper);
            Map<String, Integer> countryStats = new HashMap<>();
            
            for (UserPortFavorites favorite : favorites) {
                Ports port = portsService.getById(favorite.getPortId());
                if (port != null && port.getCountryId() != null) {
                    Countries country = countriesService.getById(port.getCountryId());
                    if (country != null) {
                        String countryName = country.getName();
                        countryStats.put(countryName, countryStats.getOrDefault(countryName, 0) + 1);
                    }
                }
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("totalFavorites", totalFavorites);
            response.put("countryStats", countryStats);
            
            return Result.success(response);
            
        } catch (Exception e) {
            logger.error("获取收藏统计失败: ", e);
            return Result.error("获取收藏统计失败: " + e.getMessage());
        }
    }

    /**
     * 计算两点间的距离（单位：公里）
     * 使用Haversine公式计算地球表面两点间的距离
     */
    private double calculateDistance(double lat1, double lng1, double lat2, double lng2) {
        final double EARTH_RADIUS = 6371; // 地球半径，单位：公里
        
        double dLat = Math.toRadians(lat2 - lat1);
        double dLng = Math.toRadians(lng2 - lng1);
        
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                   Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                   Math.sin(dLng / 2) * Math.sin(dLng / 2);
        
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        
        return EARTH_RADIUS * c;
    }

    /**
     * 获取用户创建的港口列表（支持分页）
     * @param userId 用户ID
     * @param page 页码
     * @param size 每页大小
     * @param userLat 用户当前纬度（可选，用于距离计算）
     * @param userLng 用户当前经度（可选，用于距离计算）
     * @return 用户创建的港口列表
     */
    @GetMapping("/user-ports")
    public Result<Map<String, Object>> getUserCreatedPorts(
            @RequestParam Long userId,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) Double userLat,
            @RequestParam(required = false) Double userLng) {
        
        try {
            logger.info("获取用户{}创建的港口列表，页码: {}, 每页大小: {}", userId, page, size);
            
            // 创建分页对象
            Page<Ports> pageInfo = new Page<>(page, size);
            
            // 查询用户创建的港口
            LambdaQueryWrapper<Ports> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Ports::getCreatedBy, userId)
                       .eq(Ports::getStatus, 1) // 只查询启用的港口
                       .orderByDesc(Ports::getCreatedAt);
            
            Page<Ports> portsResult = portsService.page(pageInfo, queryWrapper);
            
            // 构建返回数据
            List<Map<String, Object>> userPortsWithDetails = new ArrayList<>();
            
            for (Ports port : portsResult.getRecords()) {
                Map<String, Object> portInfo = new HashMap<>();
                
                // 港口基本信息
                portInfo.put("id", port.getId());
                portInfo.put("name", port.getName());
                portInfo.put("portCode", port.getPortCode());
                portInfo.put("description", port.getDescription());
                portInfo.put("region", port.getRegion());
                portInfo.put("timezone", port.getTimezone());
                portInfo.put("latitude", port.getLatitude());
                portInfo.put("longitude", port.getLongitude());
                portInfo.put("isPopular", port.getIsPopular());
                portInfo.put("createdAt", port.getCreatedAt());
                portInfo.put("isUserCreated", true);
                
                // 检查是否已收藏
                LambdaQueryWrapper<UserPortFavorites> favoriteQuery = new LambdaQueryWrapper<>();
                favoriteQuery.eq(UserPortFavorites::getUserId, userId)
                           .eq(UserPortFavorites::getPortId, port.getId());
                UserPortFavorites favorite = userPortFavoritesService.getOne(favoriteQuery);
                portInfo.put("isFavorited", favorite != null);
                
                // 获取国家信息
                if (port.getCountryId() != null) {
                    Countries country = countriesService.getById(port.getCountryId());
                    if (country != null) {
                        portInfo.put("countryId", country.getId());
                        portInfo.put("countryName", country.getName());
                        portInfo.put("countryNameEn", country.getNameEn());
                        portInfo.put("flag", country.getFlag());
                    }
                }
                
                // 计算距离（如果提供了用户坐标）
                if (userLat != null && userLng != null && 
                    port.getLatitude() != null && port.getLongitude() != null) {
                    double distance = calculateDistance(
                        userLat, userLng,
                        port.getLatitude().doubleValue(),
                        port.getLongitude().doubleValue()
                    );
                    portInfo.put("distance", Math.round(distance * 10.0) / 10.0);
                }
                
                userPortsWithDetails.add(portInfo);
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("list", userPortsWithDetails);
            response.put("total", portsResult.getTotal());
            response.put("current", portsResult.getCurrent());
            response.put("pages", portsResult.getPages());
            response.put("size", portsResult.getSize());
            
            return Result.success(response);
            
        } catch (Exception e) {
            logger.error("获取用户创建港口列表失败: ", e);
            return Result.error("获取用户港口列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有港口的地理位置信息（用于地图标记）
     */
    @GetMapping("/ports-locations")
    public Result<List<Map<String, Object>>> getPortsLocations() {
        try {
            logger.info("获取所有港口地理位置信息");
            
            // 获取所有启用的港口
            QueryWrapper<Ports> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1); // 只获取启用的港口
            queryWrapper.isNotNull("latitude"); // 确保有经纬度数据
            queryWrapper.isNotNull("longitude");
            queryWrapper.orderByDesc("is_popular"); // 热门港口排在前面
            queryWrapper.orderByAsc("name");
            
            List<Ports> ports = portsService.list(queryWrapper);
            
            List<Map<String, Object>> portsLocations = new ArrayList<>();
            for (Ports port : ports) {
                Map<String, Object> locationInfo = new HashMap<>();
                locationInfo.put("id", port.getId());
                locationInfo.put("name", port.getName());
                locationInfo.put("portCode", port.getPortCode());
                locationInfo.put("latitude", port.getLatitude());
                locationInfo.put("longitude", port.getLongitude());
                locationInfo.put("region", port.getRegion());
                locationInfo.put("timezone", port.getTimezone());
                locationInfo.put("isPopular", port.getIsPopular());
                locationInfo.put("description", port.getDescription());
                
                // 获取国家信息
                Countries country = countriesService.getById(port.getCountryId());
                if (country != null) {
                    locationInfo.put("countryName", country.getName());
                    locationInfo.put("countryNameEn", country.getNameEn());
                    locationInfo.put("flag", country.getFlag());
                }
                
                portsLocations.add(locationInfo);
            }
            
            logger.info("成功获取{}个港口的地理位置信息", portsLocations.size());
            return Result.success(portsLocations);
        } catch (Exception e) {
            logger.error("获取港口地理位置信息失败", e);
            return Result.error("获取港口地理位置信息失败");
        }
    }

    /**
     * 根据用户位置获取附近的港口（包含距离信息）
     */
    @GetMapping("/nearby-ports")
    public Result<List<Map<String, Object>>> getNearbyPorts(
            @RequestParam double latitude, 
            @RequestParam double longitude,
            @RequestParam(defaultValue = "50") int limit) {
        try {
            logger.info("获取坐标({}, {})附近的港口", latitude, longitude);
            
            // 获取所有启用的港口
            QueryWrapper<Ports> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1);
            queryWrapper.isNotNull("latitude");
            queryWrapper.isNotNull("longitude");
            
            List<Ports> allPorts = portsService.list(queryWrapper);
            
            // 计算距离并排序
            List<Map<String, Object>> nearbyPorts = new ArrayList<>();
            for (Ports port : allPorts) {
                double distance = calculateDistance(
                    latitude, longitude, 
                    port.getLatitude().doubleValue(), 
                    port.getLongitude().doubleValue()
                );
                
                Map<String, Object> portInfo = new HashMap<>();
                portInfo.put("id", port.getId());
                portInfo.put("name", port.getName());
                portInfo.put("portCode", port.getPortCode());
                portInfo.put("latitude", port.getLatitude());
                portInfo.put("longitude", port.getLongitude());
                portInfo.put("region", port.getRegion());
                portInfo.put("timezone", port.getTimezone());
                portInfo.put("isPopular", port.getIsPopular());
                portInfo.put("description", port.getDescription());
                portInfo.put("distance", Math.round(distance * 100.0) / 100.0); // 保留两位小数
                
                // 获取国家信息
                Countries country = countriesService.getById(port.getCountryId());
                if (country != null) {
                    portInfo.put("countryName", country.getName());
                    portInfo.put("countryNameEn", country.getNameEn());
                    portInfo.put("flag", country.getFlag());
                }
                
                nearbyPorts.add(portInfo);
            }
            
            // 按距离排序
            nearbyPorts.sort((a, b) -> Double.compare((Double) a.get("distance"), (Double) b.get("distance")));
            
            // 限制返回数量
            if (nearbyPorts.size() > limit) {
                nearbyPorts = nearbyPorts.subList(0, limit);
            }
            
            logger.info("成功获取{}个附近港口", nearbyPorts.size());
            return Result.success(nearbyPorts);
        } catch (Exception e) {
            logger.error("获取附近港口失败", e);
            return Result.error("获取附近港口失败");
        }
    }


}
